package com.youtills.core.email;

import com.youtills.core.lang.StringUtil;
import com.youtills.core.config.ConfigurationLoader;
import com.youtills.core.config.IConfigValue;
import com.youtills.core.lang.InstanceMaker;

import java.util.HashMap;
import java.util.Map;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.util.ByteArrayDataSource;

/**
 * Created by IntelliJ IDEA.
 * User: ravi
 * Date: 8/11/12
 * Time: 12:38 PM
 * To change this template use File | Settings | File Templates.
 */
public class EmailSender {

    private static EmailSender instance = new EmailSender();

    private final IEmailSender defaultSender;
    private final Map<String, IEmailSender> emailSenders;
    private static final String KEY_PREFIX = "email.sender.";

    private EmailSender() {
        defaultSender = new SmtpEmailSender();
        emailSenders = new HashMap<String, IEmailSender>();
    }

    private void send(IEmailMessage message, IEmailSender emailSender)
            throws EmailException{
        emailSender.send(message);
    }

    private IEmailSender getEmailSender(String sender){
        IEmailSender emailSender = emailSenders.get(sender);
        if(emailSender != null){
            return emailSender;
        }
        //1 - Try with sender name as a class.
        emailSender = getEmailSenderClass(sender);

        //2. Try with the config value with the prefix+name.
        if(emailSender == null){
            IConfigValue configValue = ConfigurationLoader.getConfigValue(KEY_PREFIX + sender);
            if(configValue != null && !StringUtil.isEmpty(configValue.getValue())){
                emailSender = getEmailSenderClass(configValue.getValue());
            }
        }

        //3. Try with the config value with the name.
        if(emailSender == null){
            IConfigValue configValue = ConfigurationLoader.getConfigValue(sender);
            if(configValue != null && !StringUtil.isEmpty(configValue.getValue())){
                emailSender = getEmailSenderClass(configValue.getValue());
            }
        }

        if(emailSender != null){
            emailSenders.put(sender, emailSender);
        }

        return emailSender;
    }

    private IEmailSender getEmailSenderClass(String senderClass){
        try{
            return new InstanceMaker<IEmailSender>().getInstanceOf(senderClass);
        }catch(RuntimeException re){
            return null;
        }
    }

    private void sendMessage(IEmailMessage message, String sender){
        IEmailSender emailSender = getEmailSender(sender);
        if(emailSender != null){
            send(message, getEmailSender(sender));
        }else{
            throw new EmailException("Email Sender not found for given sender = ", sender);
        }

    }

    private void sendMessage(IEmailMessage message){
        send(message, defaultSender);
    }

    public static void send(IEmailMessage message, String sender){
        instance.sendMessage(message, sender);
    }

    public static void send(IEmailMessage message){
        instance.sendMessage(message);
    }

}